package com.xyzwps.paimon.furina.middleware

import com.xyzwps.paimon.furina.common.*
import com.xyzwps.paimon.furina.infra.authenticated
import com.xyzwps.paimon.furina.infra.setAuthenticated
import com.xyzwps.paimon.furina.infra.setSessionId
import com.xyzwps.paimon.furina.infra.setUserId
import com.xyzwps.paimon.furina.modules.auth.service.JwtService
import org.springframework.stereotype.Component
import org.springframework.web.servlet.function.ServerRequest

@Component
class AuthMW(private val jwtService: JwtService) {

    fun optionalAuth(req: ServerRequest, next: RequestHandler): JsonResponse {
        val cookie = req.cookies().getFirst(Cookies.TOKEN_NAME)
        if (cookie == null) {
            req.setAuthenticated(false)
            return next(req)
        }

        val jwt = cookie.value
        val (userId, sessionId) = jwtService.verifyJwt(jwt)
        req.setAuthenticated(true)
        req.setUserId(userId)
        req.setSessionId(sessionId)
        return next(req)
    }

    fun shouldAuth(req: ServerRequest, next: RequestHandler): JsonResponse {
        return this.optionalAuth(req) {
            if (req.authenticated) {
                next(it)
            } else {
                throw AppException(AppErrorCode.NOT_AUTHENTICATED)
            }
        }
    }

    fun unauth(req: ServerRequest, next: RequestHandler): JsonResponse {
        return this.optionalAuth(req) {
            if (req.authenticated) {
                throw AppException(AppErrorCode.YOU_HAVE_BEEN_AUTHENTICATED)
            } else {
                next(it)
            }
        }
    }
}